package case15

import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"gorm.io/gorm/schema"
	"log"
	"os"
	"time"
)

func Test() {
	fmt.Println("🎯示例十五：事务")

	db, err := mysqlConnect()
	if err != nil {
		fmt.Println(err)
		return
	}

	if err := db.AutoMigrate(&UserCase15{}); err != nil {
		fmt.Println("自动创建表结构失败：", err)
		return
	}

	/*// 自动事务
	db.Transaction(func(tx *gorm.DB) error {
		//执行一些需要事务的操作

		u1 := &UserCase15{Name: "LILI", Age: 12}
		if err := tx.Create(&u1).Error; err != nil {
			// 返回任何错误都会回滚
			return err
		}

		//var _ int = 1 / 0 //模拟异常

		u2 := &UserCase15{Name: "wangwu", Age: 13}
		if err := tx.Create(&u2).Error; err != nil {
			return err
		}
		//返回 nil 提交事务
		return nil
	})*/

	/*// 手动事务
	tx := db.Begin()

	// 在事务中执行一些操作
	u1 := &UserCase15{Name: "LILI", Age: 12}
	if err := tx.Create(&u1).Error; err != nil {
		tx.Rollback()
		//return err
	}

	u2 := &UserCase15{Name: "wangwu", Age: 13}
	if err := tx.Create(&u2).Error; err != nil {
		tx.Rollback()
		//return err
	}

	//var _ int = 1 / 0 //模拟异常

	// 提交事务
	tx.Commit()*/

	CreateUserManual(db)

	fmt.Println(db)
}

// 封装事务函数
func CreateUserManual(db *gorm.DB) {
	begin := db.Begin()

	defer func() {
		// 捕获 panic 并确保回滚（防止程序崩溃时未正确处理）
		if r := recover(); r != nil {
			begin.Rollback()
			log.Println("事务提交失败：", r)
		}
	}()

	u1 := &UserCase15{Name: "LILI", Age: 12}
	err := begin.Create(&u1)
	if err.Error != nil {
		begin.Rollback()
	}

	u2 := &UserCase15{Name: "wangwu", Age: 13}
	err = begin.Create(&u2)
	// 模拟panic
	// err = begin.Create(UserInfoTmp2{Name: "测试事务4"})

	var _ int = 1 / 0 //模拟异常

	if err.Error != nil {
		begin.Rollback()
	}
	begin.Commit()

}

// 初始化连接
func mysqlConnect() (*gorm.DB, error) {
	url := "root:123456@tcp(127.0.0.1:3306)/case1?charset=utf8mb4&parseTime=True&loc=Local"

	// 配置自定义 Logger 打印sql日志
	newLogger := logger.New(
		log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
		logger.Config{
			SlowThreshold:             time.Second, // 慢 SQL 阈值
			LogLevel:                  logger.Info, // 可以设置为不同级别 Silent-不打印任何日志 Error-只打印错误日志 Warn-打印慢查询和错误 Info-打印慢查询和错误
			IgnoreRecordNotFoundError: true,        // 忽略ErrRecordNotFound（记录未找到）错误
			Colorful:                  true,        // 彩色打印
		},
	)

	db, err := gorm.Open(mysql.Open(url), &gorm.Config{
		Logger: newLogger, // 设置 Logger
		NamingStrategy: schema.NamingStrategy{
			SingularTable: true, // 关闭默认，使用表名
		},
	})
	if err != nil {
		return nil, fmt.Errorf("mysql connect err: %v", err)
	}

	return db, nil
}

// 表结构
type UserCase15 struct {
	ID         int       `gorm:"primarykey;autoIncrement"`
	Name       string    `gorm:"type:varchar(50);"`
	Age        int       `gorm:"type:int(3);"`
	CreateTime time.Time `gorm:"type:datetime;autoCreateTime"`            //自动设置创建时间
	UpdateTime time.Time `gorm:"type:datetime;default:CURRENT_TIMESTAMP"` //设置默认值
}
